package com.window24;

import com.netflix.discovery.DiscoveryManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * @EnableDiscoveryClient 将此服务注册到Eureka注册中心
 * @EnableCircuitBreaker @EnableHystrix 熔断器
 * @RefreshScope 如果此服务从Config Server上得到了最新版本的配置内容, 会被重新初始化并载入新的配置内容
 * @EnableFeignClients 开启Feign功能
 * Created by yuanfei on 2017/6/1
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableHystrix
@RefreshScope
@EnableFeignClients
@Slf4j
public class MicroServiceDemo implements ApplicationRunner {

    @Value("${foo}")
    private String foo;

    public static void main(String[] args) {

        // JVM的钩子关闭的时候(即Application Client关闭时), 要把自己在Eureka的注册取消掉
        Runtime.getRuntime().addShutdownHook(new Thread() {

            public void run() {
                DiscoveryManager.getInstance().shutdownComponent();
            }
        });
        SpringApplication.run(MicroServiceDemo.class);
    }

    /**
     * 启用Ribbon的软负载均衡
     * @return RestTemplate
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {

        RestTemplate restTemplate = new RestTemplate();
        SimpleClientHttpRequestFactory factory = (SimpleClientHttpRequestFactory) restTemplate.getRequestFactory();
        factory.setConnectTimeout(3000);
        factory.setReadTimeout(3000);
        return restTemplate;
    }

    @Override
    public void run(ApplicationArguments applicationArguments) {

        log.info(foo);
    }
}